package com.y.report.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.y.report.entity.basic.YReportApi;
import com.y.report.entity.basic.YReportDs;
import com.y.report.entity.basic.YReportSql;
import com.y.report.entity.mapper.ApiReportInfo;
import com.y.report.entity.mapper.YSqlInfos;
import com.y.report.mapper.ReportMapper;
import com.y.report.mapper.basic.YReportApiMapper;
import com.y.report.mapper.basic.YReportDsMapper;
import com.y.report.mapper.basic.YReportSqlMapper;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.commons.lang3.tuple.MutableTriple;
import org.apache.curator.shaded.com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Collections;
import java.util.List;

@Service
public class ReportService {

    private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private YReportApiMapper yReportApiMapper;

    @Autowired
    private YReportSqlMapper yReportSqlMapper;

    @Autowired
    private YReportDsMapper yReportDsMapper;


    public List<ApiReportInfo> getApiByUriOrName(String apiName, String apiCode, String apiAuth, String apiUrl, String apiMethod, String api_header) {
        return reportMapper.getApiByUriOrName(
                MapUtil.<String, Object>builder("api_name", apiName)
                        .put("api_url", apiUrl)
                        .put("api_code", apiCode)
                        .put("api_auth", apiAuth)
                        .put("api_method", apiMethod)
                        .put("api_header", api_header)
                        .build());
    }

    public MutableTriple<List<YReportApi>, List<YReportSql>, List<YReportDs>> queryCondition(ApiReportInfo eqObj, ApiReportInfo likeObj, Page page) {
        List<YReportApi> rtyReportApiLists = Lists.newArrayList();
        List<YReportSql> rtyReportSqlLists = Lists.newArrayList();
        List<YReportDs> rtyReportDsLists = Lists.newArrayList();
        MutableTriple<List<YReportApi>, List<YReportSql>, List<YReportDs>> result = MutableTriple.of(rtyReportApiLists, rtyReportSqlLists, rtyReportDsLists);

        YReportApi eqYReportApi = null;
        YReportApi likeYReportApi = null;
        List<YSqlInfos> eqYSqlInfos = Collections.emptyList();
        List<YSqlInfos> likeYSqlInfos = Collections.emptyList();
        if (eqObj != null) {
            eqYReportApi = eqObj.getYReportApi();
            eqYSqlInfos = eqObj.getYSqlInfos();
        }
        if (likeObj != null) {
            likeYReportApi = likeObj.getYReportApi();
            likeYSqlInfos = likeObj.getYSqlInfos();
        }

        if (eqYReportApi != null || likeYReportApi != null) {
            result.setLeft(yReportApiMapper.queryCondition(eqYReportApi, likeYReportApi, page));
        }

        if (CollUtil.isNotEmpty(eqYSqlInfos))
            for (int i = 0; i < Integer.max(eqYSqlInfos.size(), likeYSqlInfos.size()); i++) {
                int eqSize = eqYSqlInfos.size();
                int likeSize = likeYSqlInfos.size();
                YSqlInfos eqYSqlInfo = null;
                YSqlInfos likeYSqlInfo = null;
                if (eqSize >= i) {
                    eqYSqlInfo = eqYSqlInfos.get(i);
                }
                if (likeSize >= i) {
                    likeYSqlInfo = likeYSqlInfos.get(i);
                }

                YReportSql eqYReportSql = null;
                YReportSql likeYReportSql = null;
                YReportDs eqYReportDs = null;
                YReportDs likeYReportDs = null;
                if (eqYSqlInfo != null) {
                    eqYReportSql = eqYSqlInfo.getYReportSql();
                    likeYReportSql = likeYSqlInfo.getYReportSql();
                    eqYReportDs = eqYSqlInfo.getYReportDs();
                    likeYReportDs = likeYSqlInfo.getYReportDs();
                }
                if (eqYReportSql != null || likeYReportSql != null)
                    result.setMiddle(yReportSqlMapper.queryCondition(eqYReportSql, likeYReportSql, page));
                if (eqYReportSql != null || likeYReportSql != null)
                    result.setRight(yReportDsMapper.queryCondition(eqYReportDs, likeYReportDs, page));

            }
        return result;
    }

    @Transactional
    public int append(ApiReportInfo apiReportInfo) {
        YReportApi yRrportApi = apiReportInfo.getYReportApi();
        int apiCt = 0;
        int dsCt = 0;
        int sqlCt = 0;
        if (yRrportApi != null) {
            apiCt = this.yReportApiMapper.appendMultiple(Collections.singletonList(yRrportApi));
            Assert.isTrue(apiCt == 1, "插入api失败");
        }

        List<YSqlInfos> ySqlInfos = apiReportInfo.getYSqlInfos();
        if (CollUtil.isNotEmpty(ySqlInfos))
            for (YSqlInfos x : ySqlInfos) {
                YReportDs yRrportDs = x.getYReportDs();
                if (x.getYReportDs() != null) {
                    dsCt = yReportDsMapper.appendMultiple(Collections.singletonList(yRrportDs));
                    Assert.isTrue(dsCt == 1, "插入数据源失败");
                }
                YReportSql yRrportSql = x.getYReportSql();
                if (x.getYReportSql() != null) {
                    if (yRrportSql.getDsId() == null && yRrportDs != null)
                        yRrportSql.setDsId(yRrportDs.getDsId());
                    if (yRrportSql.getApiId() == null && yRrportApi != null)
                        yRrportSql.setApiId(yRrportApi.getApiId());
                    sqlCt = yReportSqlMapper.appendMultiple(Collections.singletonList(yRrportSql));
                    Assert.isTrue(sqlCt == 1, "插入sql失败");
                }
            }

        return apiCt != 0 && dsCt != 0 && sqlCt != 0 ? 1 : 0;
    }

    @Transactional
    public int modifyOne(ApiReportInfo queryObj, ApiReportInfo modifyObj) {
        YReportApi queryYRrportApi = queryObj.getYReportApi();
        YReportApi modifyYRrportApi = modifyObj.getYReportApi();
        int apiCt = 0;
        int sqlCt = 0;
        int dsCt = 0;
        if (queryYRrportApi != null && modifyYRrportApi != null) {
            List<YReportApi> oldYRrportApiList = yReportApiMapper.queryCondition(queryYRrportApi, null, null);
            if (CollUtil.isNotEmpty(oldYRrportApiList) && oldYRrportApiList.size() == 1) {
                apiCt = yReportApiMapper.modifyCondition(modifyYRrportApi, oldYRrportApiList.get(0));
                Assert.isTrue(apiCt == 1, String.format("修改api失败queryObj:%s,modifyObj:%s", ReflectionToStringBuilder.toString(queryObj, ToStringStyle.MULTI_LINE_STYLE), ReflectionToStringBuilder.toString(modifyObj, ToStringStyle.MULTI_LINE_STYLE)));
                log.info("修改api成功");
            }
        }

        List<YSqlInfos> queryYRrportSqlInfoList = queryObj.getYSqlInfos();
        List<YSqlInfos> modifyYRrportSqInfolList = modifyObj.getYSqlInfos();
        if (CollUtil.isNotEmpty(queryYRrportSqlInfoList) && CollUtil.isNotEmpty(modifyYRrportSqInfolList)) {
            for (int i = 0; i < modifyYRrportSqInfolList.size(); i++) {
                YSqlInfos queryYRrportSqlInfos = queryYRrportSqlInfoList.get(i);
                YSqlInfos modifyYRrportSqlInfos = modifyYRrportSqInfolList.get(i);
                if (queryYRrportSqlInfos != null && modifyYRrportSqlInfos != null) {

                    YReportSql queryYRrportSql = queryYRrportSqlInfos.getYReportSql();
                    YReportSql modifyYRrportSql = modifyYRrportSqlInfos.getYReportSql();
                    List<YReportSql> oldYRrportSqlList = yReportSqlMapper.queryCondition(queryYRrportSql, null, null);
                    if (CollUtil.isNotEmpty(oldYRrportSqlList) && oldYRrportSqlList.size() == 1) {
                        sqlCt = yReportSqlMapper.modifyCondition(modifyYRrportSql, oldYRrportSqlList.get(0));
                        Assert.isTrue(sqlCt == 1, String.format("修改sql失败queryObj:%s,modifyObj:%s", ReflectionToStringBuilder.toString(queryObj, ToStringStyle.MULTI_LINE_STYLE), ReflectionToStringBuilder.toString(modifyObj, ToStringStyle.MULTI_LINE_STYLE)));
                        log.info("修改sql成功");
                    }

                    YReportDs queryYRrportDs = queryYRrportSqlInfos.getYReportDs();
                    YReportDs modifyYRrportDs = modifyYRrportSqlInfos.getYReportDs();
                    List<YReportDs> oldYRrportDsList = yReportDsMapper.queryCondition(queryYRrportDs, null, null);
                    if (CollUtil.isNotEmpty(oldYRrportDsList) && oldYRrportDsList.size() == 1) {
                        dsCt = yReportDsMapper.modifyCondition(modifyYRrportDs, oldYRrportDsList.get(0));
                        Assert.isTrue(dsCt == 1, String.format("修改sql失败queryObj:%s,modifyObj:%s", ReflectionToStringBuilder.toString(queryObj, ToStringStyle.MULTI_LINE_STYLE), ReflectionToStringBuilder.toString(modifyObj, ToStringStyle.MULTI_LINE_STYLE)));
                        log.info("修改ds成功");
                    }
                }
            }
        }
        return NumberUtil.max(apiCt, sqlCt, dsCt);
    }

}
